﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Configuration;
using System.IO.Ports;
using System.Threading;

namespace 写号工具
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        DAL.TestDAL testDAL = new DAL.TestDAL();
        MesTool.OrderBLL orderBLL = new MesTool.OrderBLL();
        public int count = 0;
        public int qty = 0;
        SerialPort serialPort = new SerialPort();
        SerialPort serialPort2 = new SerialPort();
        public MainWindow()
        {
            InitializeComponent();

        }
        public void WriteLog(string sn,string msg)
        {
            string filePath = Environment.CurrentDirectory + "\\Log";
            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }
            string logPath = filePath + "\\" + sn + ".txt";
            try
            {
                using (StreamWriter sw = File.AppendText(logPath))
                {
                    sw.WriteLine(msg);
                    sw.Flush();
                    sw.Close();
                    sw.Dispose();
                }
            }
            catch (IOException e)
            {
                using (StreamWriter sw = File.AppendText(logPath))
                {
                    sw.WriteLine(e.Message);
                    sw.Flush();
                    sw.Close();
                    sw.Dispose();
                }
            }
        }
        /// <summary>
        /// 读取exe.config文件所有Key
        /// </summary>
        /// <returns></returns>
        public Dictionary<string, string> ReadAll()
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            foreach (string key in config.AppSettings.Settings.AllKeys)
            {
                dic[key] = config.AppSettings.Settings[key].Value;
            }
            return dic;
        }
        /// <summary>
        /// 写入exe.config文件
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void Write(string key, string value)
        {

            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            if (config.AppSettings.Settings[key] == null)
            {
                config.AppSettings.Settings.Add(key, value);
            }
            else
            {
                config.AppSettings.Settings[key].Value = value;
            }
            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("appSettings");//   重新加载新的配置文件   
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            Write("mocode", Order.Text);
            Write("port", Port.Text);
            Write("port2", Port2.Text);
            Write("scantime", Time.Text);
            Write("dbm", Dbm.Text);
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                var dic = ReadAll();
                string order = dic["mocode"];
                string port = dic["port"];
                string port2 = dic["port2"];
                Time.Text = dic["scantime"];
                Dbm.Text = dic["dbm"];
                if (string.IsNullOrEmpty(order) == false)
                {
                    Order.Text = order;
                    count = testDAL.GetCount(order);
                    qty = orderBLL.GetQty(order);
                    percent.Text = count + "/" + qty;
                    bar.Value = count;
                    bar.Maximum = qty < count ? count : qty;
                }
                var List = System.IO.Ports.SerialPort.GetPortNames().ToList();
                Port.ItemsSource = List;
                Port2.ItemsSource = List;
                if (List.Contains(port))
                {
                    Port.Text = port;
                }
                if (List.Contains(port2))
                {
                    Port2.Text = port2;
                }
                log.Document.Blocks.Clear();
                Code.Focus();
                Code.SelectAll();
            }
            catch (Exception ex)
            {
                HandyControl.Controls.MessageBox.Error(ex.Message);
            }
        }

        private void Order_KeyUp(object sender, KeyEventArgs e)
        {
            try
            {
                string order = Order.Text.ToString();
                if (string.IsNullOrEmpty(order) == false)
                {
                    count = testDAL.GetCount(order);
                    qty = orderBLL.GetQty(order);
                    percent.Text = count + "/" + qty;
                    bar.Value = count;
                    bar.Maximum = qty < count ? count : qty;
                }

            }
            catch (Exception ex)
            {
                HandyControl.Controls.MessageBox.Error(ex.Message);
            }
        }
        private void Code_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                try
                {
                    string code = Code.Text.Trim();
                    if (serialPort.IsOpen == false || serialPort.PortName != Port.Text)
                    {
                        serialPort.Close();
                        serialPort.PortName = Port.Text;
                        serialPort.BaudRate = 115200;
                        serialPort.Open();
                    }
                    if (serialPort2.IsOpen == false || serialPort2.PortName != Port2.Text)
                    {
                        serialPort2.Close();
                        serialPort2.PortName = Port2.Text;
                        serialPort2.BaudRate = 115200;
                        serialPort2.Open();
                    }
                    List<string> logs = new List<string>();
                    RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Blue, code);
                    serialPort.Write("AT+NAME=" + code + "\r\n");
                    logs.Add(serialPort.PortName + "=>AT+NAME=" + code + "\r\n");
                    RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Blue, serialPort.PortName + "=>AT+NAME=" + code + "\r\n");
                    Thread.Sleep(2000);
                    string re = PortHelper.GetData(serialPort,2000,500);
                    logs.Add(serialPort.PortName + "<=" + re);
                    RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Blue, serialPort.PortName + "<=" + re);
                    if (re.Contains(code)==false)
                    {
                        logs.Add("写号失败");
                        RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Tomato, "写号失败", 40);
                        WriteLog(code + "_NG", String.Join("\r\n", logs.ToArray()));
                        return;
                    }
                    DAL.Model.t_YF_TestRecord model = new DAL.Model.t_YF_TestRecord()
                    {
                        mocode = Order.Text.Trim(),
                        sn = code,
                        result = (re.Contains(code) && re.Contains("OK")) ? "OK" : "NG",
                        createTime = testDAL.db.GetDate()
                    };
                    if (model.result == "OK")
                    {
                        logs.Add("写号完成");
                        RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.ForestGreen, "写号完成");

                        byte scantime = 0;
                        int dbm = 0;
                        scantime = byte.Parse(Time.Text);
                        dbm = int.Parse(Dbm.Text);
                        RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Blue, $"搜索设备:{scantime}秒,>{dbm}");
                        Task.Run(() =>
                        {
                            try
                            {
                                var macs = GetBTDevices(scantime, (sbyte)dbm);
                                var pro = macs.FirstOrDefault(it => it.Address == code);
                                if (pro != null)
                                {
                                    model.info = pro.DBm + "dBm";
                                    string info = $"mocode:{model.mocode}\r\nsn:{model.sn}\r\nresult:{model.result}\r\ninfo:{model.info}\r\ntime:{model.createTime.ToString("G")}";
                                    logs.Add(info);
                                    RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Blue, info);
                                    if (testDAL.InsetTestRecord(model))
                                    {
                                        count = testDAL.GetCount(model.mocode);
                                        Dispatcher.Invoke(() =>
                                        {
                                            percent.Text = count + "/" + qty;
                                            bar.Value = count;
                                            bar.Maximum = qty < count ? count : qty;
                                        });
                                        WriteLog(code + "_OK", String.Join("\r\n", logs.ToArray()));
                                        RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.ForestGreen, "写号成功", 40);
                                    }
                                    else
                                    {
                                        logs.Add("数据上传失败");
                                        RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Tomato, "数据上传失败", 40);
                                        WriteLog(code + "_NG", String.Join("\r\n", logs.ToArray()));
                                    }
                                }
                                else
                                {
                                    logs.Add("信号强度检测失败");
                                    RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Tomato, "信号强度检测失败", 40);
                                    WriteLog(code + "_NG", String.Join("\r\n", logs.ToArray()));
                                }
                            }
                            catch (Exception ex)
                            {
                                HandyControl.Controls.Growl.Warning(ex.Message);
                            }
                            finally
                            {
                                Dispatcher.Invoke(() =>
                                {
                                    Code.Focus();
                                    Code.SelectAll();
                                });
                            }

                        });
                    }
                    else
                    {
                        logs.Add("写号失败");
                        RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Tomato, "写号失败", 40);
                        WriteLog(code + "_NG", String.Join("\r\n", logs.ToArray()));
                    }

                }
                catch (Exception ex)
                {
                    HandyControl.Controls.Growl.Warning(ex.Message);
                }
                finally
                {
                    Code.Focus();
                    Code.SelectAll();
                }
            }
        }
        /// <summary>
        /// 一发一收
        /// </summary>
        /// <param name="sendbyte">发送字节</param>
        /// <param name="delay">返回超时</param>
        /// <param name="wait">返回等待</param>
        /// <returns>返回字节</returns>
        public byte[] SendGetByte(byte[] sendbyte, int delay = 2000, int wait = 500)
        {
            try
            {
                //发送
                PortHelper.SendData(serialPort2, sendbyte);
                //写日志
                //string senddata = DateTime.Now.ToString("HH:mm:ss.fff") + "\r\nSend:" + CommonHelper.GetByteStr(sendbyte);
                //RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.SteelBlue, senddata);
                //读取返回
                byte[] recievebyte = PortHelper.GetByteData(serialPort2, delay, wait);
                //写日志
                //string recievedata = DateTime.Now.ToString("HH:mm:ss.fff") + "\r\nRecieve:" + CommonHelper.GetByteStr(recievebyte);
                //RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.SteelBlue, recievedata);
                return recievebyte;
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }
        /// <summary>
        /// 搜索蓝牙设备
        /// </summary>
        /// <param name="delay">扫描等待</param>
        /// <param name="level">最小强度过滤</param>
        /// <returns></returns>
        public List<DeviceModel> GetBTDevices(byte delay, sbyte level)
        {
            try
            {
                List<DeviceModel> macs = new List<DeviceModel>();
                RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Blue, "设置扫描参数");
                byte[] recievebyte = SendGetByte(PortModel.BtUartModel.SetScan(delay, level));
                if (CommonHelper.EqualBytes(recievebyte, PortModel.BtUartModel.SetScanOk) == false)
                {
                    RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Blue, "设置扫描参数失败");
                    return macs;
                }
                RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Blue, "设置扫描参数完成");

                RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Blue, "扫描设备");
                recievebyte = SendGetByte(PortModel.BtUartModel.Scan);
                if (recievebyte.Length == 0)
                {
                    RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Blue, "扫描设备返回超时");
                    return macs;
                }
                if (CommonHelper.EqualBytes(recievebyte, PortModel.BtUartModel.ScanOk) == false)
                {
                    RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Blue, "扫描设备失败");
                    return macs;
                }
                RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Blue, "扫描等待" + (delay * 1000) / 1000 + "秒...");
                CommonHelper.Delay(delay * 1000);
                RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Blue, "查询扫描结果");
                recievebyte = SendGetByte(PortModel.BtUartModel.GetDevices);
                if (recievebyte.Length == 0)
                {
                    RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Blue, "查询结果返回超时");
                    return macs;
                }
                if (recievebyte[0] != 0xA0 || recievebyte[1] != 0xE1)
                {
                    RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Blue, "查询结果返回数据错误");
                    return macs;
                }
                if (recievebyte[2] * 256 + recievebyte[3] != recievebyte.Length - 4 || ((recievebyte.Length - 4) % 13) != 0)
                {
                    RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Blue, "查询结果返回长度校验错误");
                    return macs;
                }
                if (recievebyte.Length == 4)
                {
                    RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Blue, "未扫描到设备");
                    return macs;
                }
                RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.Blue, "解析扫描结果");
                List<string> list = new List<string>();
                int index = 1;
                for (int i = 4; i < recievebyte.Length - 4; i += 13)
                {
                    byte[] macbyte = recievebyte.Skip(i).Take(12).ToArray();
                    DeviceModel device = new DeviceModel()
                    {
                        Address = Encoding.ASCII.GetString(macbyte),
                        DBm = (sbyte)recievebyte[i + 12]
                    };
                    if (macs.Count(it => it.Address == device.Address) == 1)
                    {
                        continue;
                    }
                    macs.Add(device);
                    string item = index + " " + device.Address + " " + device.DBm;
                    index++;
                    list.Add(item);
                    RichTextBoxBLL.RichTextBoxAppendText(log, Brushes.SteelBlue, item);
                }
                return macs;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public class DeviceModel
        {
            /// <summary>
            /// 地址
            /// </summary>
            public string Address { get; set; }
            /// <summary>
            /// 蓝牙强度
            /// </summary>
            public int DBm { get; set; }
        }
    }
}
